﻿/*----------------------------------------------------------------------------------------
*
*  Copyright 2019, Gao Hai Hui, <fromzeropoint@126.com>.  All rights reserved.
*  https://gitee.com/helloworldghh/xoskit.git
*  Use of this source code is governed by a MIT license
*  that can be found in the License file.
*
----------------------------------------------------------------------------------------*/
#include "../import/head.h"
#include "../global/head.h"
#include "../xos/head.h"
#include "crt_impl.h"

/////////////////////////////////////////////////////////////////////////////////////////
// 
namespace xos
{
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // 

    static crt_impl::POOL * pool_ptr = 0;

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //

    crt_impl::crt_impl()
    {
    }

    crt_impl::~crt_impl()
    {
        term();
    }

    ////////////////////////////////////////////////////////////////////////////////////
    // 

    int crt_impl::get_addr( POOL *** pppPool, LIST *** pppList )
    {
        int ret = 0;
        if( pppPool )
        {
            *pppPool = &pool_ptr;
        }
        if( pppList )
        {
            *pppList = 0;
        }
        return ret;
    }

    int crt_impl::init()
    {
        int nRet = 0;
        return nRet;
    }

    int crt_impl::term()
    {
        int nRet = 0;
        return nRet;
    }

    ////////////////////////////////////////////////////////////////////////////////////
    // 

	const void * crt_impl::mem_find( const void * lpMainMem, int nMainLen, const void * lpSubMem, int nSubLen )
	{
		const char * lpszMainMem = (const char *)lpMainMem;
		const char * lpszSubMem = (const char *)lpSubMem;
		int nStep = nMainLen - nSubLen + 1;
		const char * lpszRet = 0;

		for( int i = 0; i < nStep; ++i )
		{
			int ret = memcmp( lpszMainMem + i, lpszSubMem, nSubLen );
			if( 0 == ret )
			{
				lpszRet = lpszMainMem + i;
				break;
			}
		}

		return lpszRet;
	}

	int crt_impl::memmove( void * lpDst, const void * lpSrc, int nSize )
	{
		const char * lpszSrc = (const char *)lpSrc;
		char * lpszDst = (char *)lpDst;
		int ret = 0;
		::memmove( lpszDst, lpszSrc, nSize );
		return ret;
	}

	int crt_impl::memcpy( void * lpDst, const void * lpSrc, int nSize )
	{
		int ret = 0;
		::memcpy( lpDst, lpSrc, nSize );
		return ret;
	}

	int crt_impl::memset( void * lpDst, int nValue, int nSize )
	{
		int ret = 0;
		::memset( lpDst, nValue, nSize );
		return ret;
	}

    const char * crt_impl::strrstr( const char * lpszStr, const char * lpszSubStr, bool bCaseSensitive )
    {
        const char * pRet = 0;
        int nRet = 0;

        int tLen2 = 0;
        int tLen1 = 0;

        if( 0 == nRet )
        {
            tLen2 = ( int )::strlen( lpszSubStr );
            tLen1 = ( int )::strlen( lpszStr );

            if( tLen1 < tLen2 )
            {
                nRet = 1;
            }
        }

        if( bCaseSensitive )
        {
            for( int i = tLen1 - tLen2; i >= 0; --i )
            {
                if( 0 == ::strncmp( lpszStr + i, lpszSubStr, tLen2 ) )
                {
                    pRet = lpszStr + i;
                    break;
                }
            }
        }
        else
        {
            for( int i = tLen1 - tLen2; i >= 0; --i )
            {
                if( 0 == ::strncasecmp( lpszStr + i, lpszSubStr, tLen2 ) )
                {
                    pRet = lpszStr + i;
                    break;
                }
            }
        }

        return pRet;
    }

    const char * crt_impl::strstr( const char * lpszStr, const char * lpszSubStr, bool bCaseSensitive )
    {
        const char * pRet = 0;
        int nRet = 0;

        if( bCaseSensitive )
        {
            pRet = ::strstr( lpszStr, lpszSubStr );
            nRet = 1;
        }

        int tLen2 = 0;
        int tLen1 = 0;

        if( 0 == nRet )
        {
            tLen2 = ( int )::strlen( lpszSubStr );
            tLen1 = ( int )::strlen( lpszStr );

            if( tLen1 < tLen2 )
            {
                nRet = 1;
            }
        }

        if( 0 == nRet )
        {
            for( int i = 0; i <= tLen1 - tLen2; ++i )
            {
                if( 0 == ::strncasecmp( lpszStr + i, lpszSubStr, tLen2 ) )
                {
                    pRet = lpszStr + i;
                    break;
                }
            }
        }

        return pRet;
    }

    char * crt_impl::strrstr( char * lpszStr, const char * lpszSubStr, bool bCaseSensitive )
    {
        return ( char * )strrstr( ( const char * )lpszStr, lpszSubStr, bCaseSensitive );
    }

    char * crt_impl::strstr( char * lpszStr, const char * lpszSubStr, bool bCaseSensitive )
    {
        return ( char * )strstr( ( const char * )lpszStr, lpszSubStr, bCaseSensitive );
    }

    const char * crt_impl::strrchr( const char * lpszStr, char c )
    {
        return ::strrchr( lpszStr, c );
    }

    const char * crt_impl::strchr( const char * lpszStr, char c )
    {
        return ::strchr( lpszStr, c );
    }

    char * crt_impl::strrchr( char * lpszStr, char c )
    {
        return ::strrchr( lpszStr, c );
    }

    char * crt_impl::strchr( char * lpszStr, char c )
    {
        return ::strchr( lpszStr, c );
    }

    int crt_impl::vsnprintf( char * lpszBuf, int nBufSize, const char * format, va_list argptr )
    {
        int nRet = 0;
        nRet = ::vsnprintf( lpszBuf, nBufSize, format, argptr );
        return nRet;
    }

    int crt_impl::sprintf( char * buf, int nBufSize, const char * lpszFormat, ... )
    {
        int nRet = 0;

        va_list  va;
        va_start( va, lpszFormat );
        nRet = ::vsnprintf( buf, nBufSize, lpszFormat, va );
        va_end( va );

        return nRet;
    }

    char * crt_impl::strptime( const char * buf, const char * fmt, struct tm * tm )
    {
        return ::strptime( buf, fmt, tm );
    }

    int crt_impl::gets( char * lpszBuf, int nBufSize )
    {
        int nRet = 0;
        ::fgets( lpszBuf, nBufSize - 1, stdin );
        return nRet;
    }

    double crt_impl::atof( const char * lpszStr )
    {
        return ::atof( lpszStr );
    }

    xos_i64 crt_impl::atoi64( const char * lpszStr )
    {
        double fData = ::atof( lpszStr );
        return ( xos::xos_i64 )fData;
    }

    int crt_impl::atoi( const char * lpszStr )
    {
        return ::atoi( lpszStr );
    }

    int crt_impl::atol( const char * lpszStr )
    {
        return ::atol( lpszStr );
    }

    int crt_impl::uppercase( const char * lpszSrc, char * lpszDst )
    {
        int nRet = 0;

        while( char c = *lpszSrc++ )
        {
            *lpszDst++ = ::toupper( c );
        }

        *lpszDst = 0;

        return nRet;
    }

    int crt_impl::lowercase( const char * lpszSrc, char * lpszDst )
    {
        int nRet = 0;

        while( char c = *lpszSrc++ )
        {
            *lpszDst++ = ::tolower( c );
        }

        *lpszDst = 0;

        return nRet;
    }

    int crt_impl::toupper( char c )
    {
        int nRet = ::toupper( c );
        return nRet;
    }

    int crt_impl::tolower( char c )
    {
        int nRet = ::tolower( c );
        return nRet;
    }

    char * crt_impl::strncpy( char * lpszDst, int nBufSize, const char * lpszSrc, int nLen )
    {
        int dstLen = ::strlen( lpszDst );
        int srcLen = nLen;
        int len = srcLen + dstLen;
        if( nBufSize > len )
        {
            ::strncpy( lpszDst, lpszSrc, len );
            lpszDst[len] = 0;
        }
        else
        {
            assert_valid( false );
        }
        return lpszDst;
    }

    char * crt_impl::strcpy( char * lpszDst, int nBufSize, const char * lpszSrc )
    {
        int len = ::strlen( lpszSrc );
        if( nBufSize > len )
        {
            ::strcpy( lpszDst, lpszSrc );
        }
        else
        {
            assert_valid( false );
        }
        return lpszDst;
    }

    char * crt_impl::strcat( char * lpszDst, int nBufSize, const char * lpszSrc )
    {
        int dstLen = ::strlen( lpszDst );
        int srcLen = ::strlen( lpszSrc );
        int len = srcLen + dstLen;
        len = nBufSize - 1 > len ? len : nBufSize - 1;
        if( nBufSize > len )
        {
            ::strcat( lpszDst, lpszSrc );
        }
        else
        {
            assert_valid( false );
        }
        return lpszDst;
    }

    int crt_impl::strlen( const char * lpszStr )
    {
        int ret = 0;
        if( lpszStr )
        {
            ret = ::strlen( lpszStr );
        }
        return ret;
    }

    int crt_impl::stricmp( const char * lpszStr1, const char * lpszStr2 )
    {
        int nRet = 0;

        if( lpszStr1 && lpszStr2 )
        {
            nRet = ::strcasecmp( lpszStr1, lpszStr2 );
        }
        else
        {
            nRet = 1;
        }

        return nRet;
    }

    int crt_impl::strcmp( const char * lpszStr1, const char * lpszStr2 )
    {
        int nRet = 0;

        if( lpszStr1 && lpszStr2 )
        {
            nRet = ::strcmp( lpszStr1, lpszStr2 );
        }
        else
        {
            nRet = 1;
        }

        return nRet;
    }

    int crt_impl::assert_valid( bool bAssert )
    {
        int nRet = 0;
        assert( bAssert );
        return nRet;
    }

    // 
    // if uSeed is 0, sys will add seed
    // 
    int crt_impl::srand( xos::xos_u32 uSeed )
    {
        int nRet = 0;

        if( 0 == uSeed )
        {
            uSeed = ( xos::xos_u32 )time( 0 );
        }

        ::srand( uSeed );

        return nRet;
    }

    int crt_impl::rand( int nMax )
    {
        int nRet = 0;
        nRet = ::rand() % nMax;
        return nRet;
    }
} // xos
